/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package algoritmosprobab;

import java.util.ArrayList;

/**
 *
 * @author jorgeorm
 */
public class NReinas_Vegas {
    
    private int[] tablero; // Representacion tablero de juego
    private ArrayList<Integer> posibilidades;
    private int nReinas; //cantidad de reinas
    private boolean [] libre; //Arreglo auxiliar para medir aptitud, indica si una reina
                              //está libre de ataque.
    private GeneradorStandardMinimo generador;
    
    public NReinas_Vegas(int numeroReinas){
        this.nReinas = numeroReinas;
        tablero = new int[this.nReinas];
        generador= new GeneradorStandardMinimo((int)System.currentTimeMillis());
    }
    
    private void initTablero(){
        posibilidades = null;
        posibilidades = new ArrayList(this.nReinas);
        for(int i=0;i<this.nReinas;i++){
            posibilidades.add(i);//Lista de posiciones posibles para situar una reina.
            tablero[i]=-1;//Valor de bandera que indica que no se ha situado reina en dicha posicion
        }
    }
    
    public void mostrarSolucion(){
        System.out.println("Solución!!: ");
        char reina;
        for(int i= 0; i<nReinas; i++){
            System.out.print(tablero[i]+",");
        }
        System.out.println();
        
        for(int i=0; i < nReinas; i++){
            for(int j=0; j < nReinas; j++){
                if(tablero[j] == i) {
                    reina = '*';
                }else {
                    reina = ' ';
                }
                System.out.print("|"+reina);
                if(j==nReinas-1){
                    System.out.print("|");
                }
            }
            System.out.println();
        }
    }
    
    public boolean lasVegas(){
        initTablero();
        boolean exito = true;
        ArrayList<Integer>posibilidadesTMP;
        int posicionReina;//Posicion escogida de las posibilidades
        int numAleat;//Numero aleatorio del generador
        
        UBICARREINAS:for(int i=0; i<nReinas; i++){//Ciclo que situa reina por reina
            posibilidadesTMP=new ArrayList(posibilidades);
            if(i>0){
                //Verifico las posiciones posibles para la reina actual (i-esima reina)
                filtrarPosibilidades(i, posibilidadesTMP);
                if(posibilidadesTMP.isEmpty()){
                    exito = false;
                    generador = new GeneradorStandardMinimo((int)System.currentTimeMillis());
                    break UBICARREINAS;
                }
            }
            numAleat = generador.nextInt(posibilidadesTMP.size()-1);//id aleatorio de las posiciones posibles para i-esima reina
            posicionReina = posibilidadesTMP.remove(numAleat);//Saco la posición de la reina de las posibilidades posibles
            posibilidades.remove(new Integer(posicionReina));
            
            tablero[i]=posicionReina;
        }
        
        return exito;
    }
    
    private void filtrarPosibilidades(int reinaActual, ArrayList<Integer> posibilidades ){
        int difPosiciones;
        int posInvalida;
        for(int i=0; i<reinaActual;i++){
            difPosiciones = reinaActual-i;
            
            posInvalida = tablero[i]+difPosiciones;
            if(posInvalida<nReinas){
                posibilidades.remove(new Integer(posInvalida));
            }
            
            posInvalida = tablero[i]-difPosiciones;
            if(posInvalida>=0){
                posibilidades.remove(new Integer(posInvalida));
            }
        }
    }
    public int[] getTablero() {
        return tablero;
    }

    public void setTablero(int[] tablero) {
        this.tablero = tablero;
    }

    public int getnReinas() {
        return nReinas;
    }

    public void setnReinas(int nReinas) {
        this.nReinas = nReinas;
    }

    public boolean[] getLibre() {
        return libre;
    }

    public void setLibre(boolean[] libre) {
        this.libre = libre;
    }
    
}
